package com.example.graphmovieapp.domain.entity;

import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
import org.springframework.data.neo4j.core.schema.Relationship;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import com.alibaba.fastjson2.annotation.JSONField;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Max;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Movie实体类，表示图数据库中的电影节点
 * 
 * @author GraphMovieApp
 * @version 1.0
 */
@Node("Movie")
public class Movie {
    
    /**
     * 电影ID，主键
     */
    @Id
    @GeneratedValue
    private Long id;
    
    /**
     * 电影标题
     */
    @Property("title")
    @NotBlank(message = "电影标题不能为空")
    private String title;
    
    /**
     * 发行年份
     */
    @Property("released")
    @Min(value = 1800, message = "发行年份不能早于1800年")
    @Max(value = 2100, message = "发行年份不能晚于2100年")
    private Integer released;
    
    /**
     * 演员列表（ACTED_IN关系的入向）
     */
    @Relationship(type = "ACTED_IN", direction = Relationship.Direction.INCOMING)
    @JSONField(serialize = false, deserialize = false)
    private List<Person> actors = new ArrayList<>();

    /**
     * 导演列表（DIRECTED关系的入向）
     */
    @Relationship(type = "DIRECTED", direction = Relationship.Direction.INCOMING)
    @JSONField(serialize = false, deserialize = false)
    private List<Person> directors = new ArrayList<>();
    
    /**
     * 默认构造函数
     */
    public Movie() {
    }
    
    /**
     * 带参数的构造函数
     * 
     * @param title 电影标题
     * @param released 发行年份
     */
    public Movie(String title, Integer released) {
        this.title = title;
        this.released = released;
    }
    
    /**
     * 获取电影ID
     * 
     * @return 电影ID
     */
    public Long getId() {
        return id;
    }
    
    /**
     * 设置电影ID
     * 
     * @param id 电影ID
     */
    public void setId(Long id) {
        this.id = id;
    }
    
    /**
     * 获取电影标题
     * 
     * @return 电影标题
     */
    public String getTitle() {
        return title;
    }
    
    /**
     * 设置电影标题
     * 
     * @param title 电影标题
     */
    public void setTitle(String title) {
        this.title = title;
    }
    
    /**
     * 获取发行年份
     * 
     * @return 发行年份
     */
    public Integer getReleased() {
        return released;
    }
    
    /**
     * 设置发行年份
     * 
     * @param released 发行年份
     */
    public void setReleased(Integer released) {
        this.released = released;
    }
    
    /**
     * 获取演员列表
     * 
     * @return 演员列表
     */
    public List<Person> getActors() {
        return actors;
    }
    
    /**
     * 设置演员列表
     * 
     * @param actors 演员列表
     */
    public void setActors(List<Person> actors) {
        this.actors = actors;
    }
    
    /**
     * 获取导演列表
     * 
     * @return 导演列表
     */
    public List<Person> getDirectors() {
        return directors;
    }
    
    /**
     * 设置导演列表
     * 
     * @param directors 导演列表
     */
    public void setDirectors(List<Person> directors) {
        this.directors = directors;
    }
    
    /**
     * 添加演员
     * 
     * @param actor 演员
     */
    public void addActor(Person actor) {
        if (!actors.contains(actor)) {
            actors.add(actor);
        }
    }
    
    /**
     * 移除演员
     * 
     * @param actor 演员
     */
    public void removeActor(Person actor) {
        actors.remove(actor);
    }
    
    /**
     * 添加导演
     * 
     * @param director 导演
     */
    public void addDirector(Person director) {
        if (!directors.contains(director)) {
            directors.add(director);
        }
    }
    
    /**
     * 移除导演
     * 
     * @param director 导演
     */
    public void removeDirector(Person director) {
        directors.remove(director);
    }
    
    /**
     * 重写equals方法
     * 
     * @param o 比较对象
     * @return 是否相等
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Movie movie = (Movie) o;
        return Objects.equals(id, movie.id) && 
               Objects.equals(title, movie.title) && 
               Objects.equals(released, movie.released);
    }
    
    /**
     * 重写hashCode方法
     * 
     * @return 哈希值
     */
    @Override
    public int hashCode() {
        return Objects.hash(id, title, released);
    }
    
    /**
     * 重写toString方法
     * 
     * @return 字符串表示
     */
    @Override
    public String toString() {
        return "Movie{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", released=" + released +
                '}';
    }
}